<template>
  <BaseCard class="over-view" :gap="outGap" :class="cardClass">
    <div
      v-if="!noThumb"
      class="over-view__thumb"
      :class="thumbClass"
      :style="thumbStyle"
    >
      <div class="over-view__thumb-wrap" :style="thumbWrapStyle">
        <div class="over-view__thumb-inner">
          <slot name="thumb">
            <VanImage
              :fit="fit"
              :src="formatImageUrl(thumb)"
              height="100%"
              width="100%"
              :lazyLoad="lazyLoad"
              @error="onImageError"
              @load="onImageLoaded"
            ></VanImage>
          </slot>
        </div>
      </div>
    </div>
    <BaseCard
      :gap="contentGap"
      :bg="false"
      :is-radius="false"
      class="over-view__content"
      :class="contentClass"
    >
      <slot name="content">
        <div class="over-view__top">
          <slot name="title">
            <BaseTitle
              :title="title"
              :is-bold="titleBold"
              :max-line="titleLine"
              gap="0"
              :size="titleSize"
            >
              <template #right>
                <slot name="title-right"></slot>
              </template>
            </BaseTitle>
          </slot>
          <slot></slot>
        </div>

        <div v-if="slots.middle" class="over-view__middle">
          <slot name="middle"></slot>
        </div>

        <div v-if="slots.bottom" class="over-view__bottom">
          <slot name="bottom"></slot>
        </div>
      </slot>
    </BaseCard>
  </BaseCard>
</template>

<script setup>
import { computed, useSlots } from "vue";
import { normaliseCssSize, getSizeClass } from "../utils/cssUtils";
import { formatImageUrl } from "@/utils/imageUtils.js";

let props = defineProps({
  // 用于覆盖BaseCard的gap
  gap: {
    type: [String, Boolean, Number],
    default: undefined,
  },

  thumb: String,
  lazyLoad: Boolean,
  thumbSize: {
    type: String,
    default: "sm",
  },
  thumbBorder: Boolean,
  fit: {
    default: "cover",
  },
  noThumb: Boolean,

  title: String,
  titleSize: {
    type: String,
    default: "sm",
  },
  titleLine: {
    default: "2",
  },
  titleBold: {
    type: Boolean,
    default: false,
  },

  isVertical: Boolean,
  // 垂直时图片高度是否强制正方形
  isSquare: {
    type: Boolean,
    default: true,
  },
  isRadius: Boolean,
  // 高度比例 百分比
  thumbRatio: {
    default: 100,
  },
  // 垂直是图片是否铺满宽度
  isThumbFill: {
    type: Boolean,
    default: true,
  },

  // 内容是否垂直居中
  centered: Boolean,
});

const emit = defineEmits(["image-error", "image-loaded"]);

let slots = useSlots();

let cardClass = computed(() => {
  return {
    "over-view--vertical": props.isVertical,
    "over-view--radius": props.isRadius,
  };
});

let outGap = computed(() => {
  return props.isVertical && props.isThumbFill ? false : props.gap;
});

let contentGap = computed(() => {
  return !props.isVertical || !props.isThumbFill ? false : props.gap;
});

let thumbClass = computed(() => {
  return {
    ...getSizeClass(props.thumbSize, "over-view__thumb--"),
    "over-view__thumb--square": props.isSquare,
    "over-view__thumb--border": props.thumbBorder,
  };
});
let thumbStyle = computed(() => {
  return {
    ...normaliseCssSize(props.thumbSize, "width"),
    ...normaliseCssSize(props.thumbSize, "height"),
  };
});
const thumbWrapStyle = computed(() => {
  const style = {};
  if (props.isSquare && props.thumbRatio) {
    style["padding-top"] = `${props.thumbRatio}%`;
  }
  return style;
});

let contentClass = computed(() => {
  return {
    "over-view__content--centered": props.centered,
  };
});

const onImageError = () => {
  emit("image-error");
};
const onImageLoaded = () => {
  emit("image-loaded");
};
</script>

<style lang="scss" scoped>
.over-view {
  --goods-image-md: 100px;
  --goods-image-sm: 66px;
  --goods-image-gap: var(--dx-size-gap-xs);
  --goods-item-gap: var(--dx-size-gap-xs);
  --goods-image-radius: var(--dx-size-radius-md);
  --goods-image-background: var(--dx-color-bg-l1);

  display: flex;
  gap: var(--goods-image-gap);
  position: relative;
  font-size: var(--dx-size-text-md);

  &__thumb {
    position: relative;
    flex: none;
    width: var(--goods-image-md);
    overflow: hidden;

    &--sm {
      width: var(--goods-image-sm);
    }

    &-inner {
      height: 100%;
      width: 100%;
      overflow: hidden;

      .van-image {
        background-color: var(--goods-image-background);
      }
    }
    &--square {
      .over-view__thumb-wrap {
        position: relative;
        height: 0;
        padding-top: 100%;
        .over-view__thumb-inner {
          position: absolute;
          top: 0;
          left: 0;
        }
      }
    }
    &--border {
      border: var(--dx-border);
    }
  }

  &__content,
  &__top,
  &__middle,
  &__bottom {
    display: flex;
    flex-direction: column;
    gap: var(--goods-item-gap);
  }

  &__content {
    flex: auto;
    justify-content: space-between;
    overflow-x: hidden;

    &--centered {
      justify-content: center;
    }
  }
  &:not(&--vertical) &__content {
    padding: calc(var(--goods-item-gap) / 2) 0;
  }

  &--vertical {
    flex-direction: column;

    .over-view__thumb {
      width: 100%;
    }

    .over-view__content {
      padding-top: 0;
    }
  }

  &--radius,
  &--radius &__thumb-inner {
    border-radius: var(--goods-image-radius);
  }
}
.van-image {
  display: block;
}
</style>
